package com.xuanxuan.socketdemo.activity;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.xuanxuan.socketdemo.R;
import com.ywicc.commlibs.socket.ClientManger;
import com.ywicc.commlibs.socket.ClientManger.ClientMangerImpl;
import com.ywicc.commlibs.socket.ServerService;
import com.ywicc.commlibs.socket.ServerService.ServerServiceImpl;
import com.ywicc.commlibs.socket.SocketUtils;

import java.lang.ref.WeakReference;
import java.nio.charset.StandardCharsets;

public class TestActivity extends AppCompatActivity implements OnClickListener, ClientMangerImpl, ServerServiceImpl {

    private final static String TAG = "TestActivity";

    private TestHandler handler;
    private ClientManger clientManger;
    private ServerService service;
    private EditText et_server;
    private EditText et_client;
    private TextView tv_server;
    private TextView tv_client;
    private String strClientData;
    private String strServerData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_activity);

        // 初始化控件
        initView();

        handler = new TestHandler(TestActivity.this, this.getMainLooper());
    }

    /**
     * 初始化控件
     */
    public void initView() {
        // 太累了，写不动了才这样写
        findViewById(R.id.btn_test_start).setOnClickListener(this);
        findViewById(R.id.btn_test_server_send).setOnClickListener(this);
        findViewById(R.id.btn_test_server_receive).setOnClickListener(this);
        findViewById(R.id.btn_test_server_stop_receive).setOnClickListener(this);
        findViewById(R.id.btn_test_client_send).setOnClickListener(this);
        findViewById(R.id.btn_test_client_receive).setOnClickListener(this);
        findViewById(R.id.btn_test_client_stop_receive).setOnClickListener(this);
        findViewById(R.id.btn_test_stop).setOnClickListener(this);

        et_server = findViewById(R.id.et_test_server);
        et_client = findViewById(R.id.et_test_client);

        tv_server = findViewById(R.id.tv_test_server);
        tv_client = findViewById(R.id.tv_test_client);
    }

    /**
     * 初始化方法
     */
    public void startTest() {
        // 启动服务端 Service
        Intent intent = new Intent(TestActivity.this, ServerService.class);
        startService(intent);

        Log.w(TAG, "Server Start");

        // 延时绑定对应的服务
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                // 绑定服务，以便后续调用 Service 中的方法
                bindService(intent, connection, Context.BIND_AUTO_CREATE);

                Log.w(TAG, "Bind server");
            }
        }, 2000);

        // 延时初始化客户端
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                // 初始化客户端 Socket
                clientManger = new ClientManger();

                // 使用本地 IP 进行连接
                clientManger.initSocket("127.0.0.1", SocketUtils.IPPort);

                Log.w(TAG, "Client socket init");
            }
        }, 4000);

        // 延时实现回调接口
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                service.setServerServiceImpl(TestActivity.this);
                clientManger.setClientMangerImpl(TestActivity.this);

                Toast.makeText(TestActivity.this, "初始化成功", Toast.LENGTH_LONG).show();
            }
        }, 6000);
    }

    /**
     * 点击事项的实现
     */
    @SuppressLint("NonConstantResourceId")
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btn_test_start:
                Toast.makeText(TestActivity.this, "请等待初始化完成", Toast.LENGTH_SHORT).show();
                startTest();
                break;
            case R.id.btn_test_server_send:
                String strServerSendData = et_server.getText().toString();
                // 将输入的内容转换为 byte
                service.sendData(strServerSendData.getBytes());
                break;
            case R.id.btn_test_server_receive:
                service.startReceive();
                break;
            case R.id.btn_test_server_stop_receive:
                service.stopReceive();
                break;
            case R.id.btn_test_client_send:
                String strClientSendData = et_client.getText().toString();
                // 将输入的内容转换为 byte
                clientManger.sendData(strClientSendData.getBytes());
                break;
            case R.id.btn_test_client_receive:
                clientManger.startLongReceiveData();
                break;
            case R.id.btn_test_client_stop_receive:
                clientManger.stopLongReceiveData();
                break;
            case R.id.btn_test_stop:
                clientManger.stopLongReceiveData();
                clientManger.stopSocket();

                unbindService(connection);
                stopService(new Intent(TestActivity.this, ServerService.class));
                break;
        }
    }

    // 绑定服务器所需要的 connection
    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            // 绑定 Service， 获取Service对象
            ServerService.ServerBinder binder = (ServerService.ServerBinder) iBinder;
            service = binder.getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            // 空实现
        }
    };

    /**
     * 客户端数据接收回调
     *
     * @param data 接收的数据
     */
    @Override
    public void callBackClientReceiveData(byte[] data) {
        if (data.length > 0) {
            strClientData = new String(data, StandardCharsets.UTF_8);

            Log.w(TAG, "接收到的数据为: " + strClientData);
        }

        // 同步更新 TextView
        Message message = handler.obtainMessage();
        message.what = 1;
        handler.sendMessage(message);
    }

    /**
     * 服务端数据接收回调
     *
     * @param data 接收的数据
     */
    @Override
    public void callBackServerReceiveData(byte[] data) {
        if (data.length > 0) {
            strServerData = new String(data, StandardCharsets.UTF_8);

            Log.w(TAG, "接收到的数据为: " + strServerData);
        }

        // 同步更新 TextView
        Message message = handler.obtainMessage();
        message.what = 2;
        handler.sendMessage(message);
    }

    /**
     * Handler 静态封装，防止内存泄漏
     */
    static class TestHandler extends Handler {
        private WeakReference<TestActivity> weakActivity;

        public TestHandler(TestActivity activity, Looper looper) {
            super(looper);
            weakActivity = new WeakReference<>(activity);
        }

        @SuppressLint("SetTextI18n")
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);

            TestActivity activity = weakActivity.get();

            switch (msg.what) {
                case 1:
                    activity.tv_client.setText("接收数据: " + activity.strClientData);
                    break;
                case 2:
                    activity.tv_server.setText("接收数据: " + activity.strServerData);
                    break;
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        clientManger.stopLongReceiveData();
        clientManger.stopSocket();

        unbindService(connection);
        stopService(new Intent(TestActivity.this, ServerService.class));
    }
}

/*
* 具体说明
*
* 服务端：
*   服务端使用了 Service
*       具体使用流程:
*           startService -> bindService -> setServerServiceImpl() -> 逻辑任务 -> unbindService -> stopService
*
*       具体方法:
*           sendData(byte[]):       发送数据
*
* 客户端:
*   客户端是直接类封装
*       具体使用流程:
*           new ClientManger() -> initSocket() -> startLongReceiveData() -> sendData() -> stopLongReceiveData() -> stopSocket()
*
*       具体方法:
*           initSocket(String strIP, int port):     初始化 Socket，并指定 IP 和 端口号
*           startLongReceiveData()                  长时间运行数据接收
*           sendData(byte[]):                       发送数据
*           stopLongReceiveData()                   停止长时间运行数据接收
*           stopSocket()                            关闭Socket
*
*       建议:
*           建议在 Activity 销毁时，执行 stopLongReceiveData 和 stopSocket 方法
*
* */